From ffcd60398a93ea7f208f4cbae3ae5b7009174253 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Fri, 11 Jan 2002 23:56:28 +0000 Subject: [PATCH] Fixes contributed by Archaeopteryx Software: This is a first small part of 2002-01-12 Tor Lillqvist Fixes contributed by Archaeopteryx Software: This is a first small part of their changes. Will commit more later. * gdk/win32/*.c: Add some more checks for failed GDI calls. If a call fails, don't use bogus values. * gdk/win32/gdkcursor-win32.c (_gdk_win32_data_to_wcursor): Plug memory leak: g_free() the AND and XOR bitmaps after use. (_gdk_cursor_destroy): If we are destroying the current Windows cursor, set the Windows cursor to none first. * gdk/win32/gdkgc-win32.c (predraw_set_foreground): Delete the old brush that was in the DC, like the win32-procution branch does. I guess this plugs a resource leak? With the HDC cache, the old brush might be something we created ourselves, and not a stock brush. And it doesn't do any harm to call DeleteObject on stock brushes. * gdk/win32/gdkwindow-win32.c (gdk_window_impl_win32_finalize): If the window has a cursor which is the current Windows cursor, before destroying it set the current Windows cursor to none. (gdk_window_set_cursor): Also here, if destroying the current Windows cursor, set the current Windows cursor to none first. (gdk_window_get_pointer): Revamp logic. --- ChangeLog | 27 ++++++++ ChangeLog.pre-2-0 | 27 ++++++++ ChangeLog.pre-2-10 | 27 ++++++++ ChangeLog.pre-2-2 | 27 ++++++++ ChangeLog.pre-2-4 | 27 ++++++++ ChangeLog.pre-2-6 | 27 ++++++++ ChangeLog.pre-2-8 | 27 ++++++++ gdk/win32/gdkcolor-win32.c | 3 +- gdk/win32/gdkcursor-win32.c | 7 ++ gdk/win32/gdkgc-win32.c | 10 ++- gdk/win32/gdkwindow-win32.c | 125 ++++++++++++++++++++++-------------- 11 files changed, 283 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index bb8b23e187..9d472601d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2002-01-12 Tor Lillqvist + + Fixes contributed by Archaeopteryx Software: This is a first small + part of their changes. Will commit more later. + + * gdk/win32/*.c: Add some more checks for failed GDI calls. If a + call fails, don't use bogus values. + + * gdk/win32/gdkcursor-win32.c (_gdk_win32_data_to_wcursor): Plug + memory leak: g_free() the AND and XOR bitmaps after use. + (_gdk_cursor_destroy): If we are destroying the current Windows + cursor, set the Windows cursor to none first. + + * gdk/win32/gdkgc-win32.c (predraw_set_foreground): Delete the old + brush that was in the DC, like the win32-procution branch does. I + guess this plugs a resource leak? With the HDC cache, the old + brush might be something we created ourselves, and not a stock + brush. And it doesn't do any harm to call DeleteObject on stock + brushes. + + * gdk/win32/gdkwindow-win32.c (gdk_window_impl_win32_finalize): If + the window has a cursor which is the current Windows cursor, + before destroying it set the current Windows cursor to none. + (gdk_window_set_cursor): Also here, if destroying the current + Windows cursor, set the current Windows cursor to none first. + (gdk_window_get_pointer): Revamp logic. + 2002-01-10 jacob berkman * gtk/gtkwidget.c (gtk_widget_add_events): actually iterate diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index bb8b23e187..9d472601d5 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,30 @@ +2002-01-12 Tor Lillqvist + + Fixes contributed by Archaeopteryx Software: This is a first small + part of their changes. Will commit more later. + + * gdk/win32/*.c: Add some more checks for failed GDI calls. If a + call fails, don't use bogus values. + + * gdk/win32/gdkcursor-win32.c (_gdk_win32_data_to_wcursor): Plug + memory leak: g_free() the AND and XOR bitmaps after use. + (_gdk_cursor_destroy): If we are destroying the current Windows + cursor, set the Windows cursor to none first. + + * gdk/win32/gdkgc-win32.c (predraw_set_foreground): Delete the old + brush that was in the DC, like the win32-procution branch does. I + guess this plugs a resource leak? With the HDC cache, the old + brush might be something we created ourselves, and not a stock + brush. And it doesn't do any harm to call DeleteObject on stock + brushes. + + * gdk/win32/gdkwindow-win32.c (gdk_window_impl_win32_finalize): If + the window has a cursor which is the current Windows cursor, + before destroying it set the current Windows cursor to none. + (gdk_window_set_cursor): Also here, if destroying the current + Windows cursor, set the current Windows cursor to none first. + (gdk_window_get_pointer): Revamp logic. + 2002-01-10 jacob berkman * gtk/gtkwidget.c (gtk_widget_add_events): actually iterate diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index bb8b23e187..9d472601d5 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,30 @@ +2002-01-12 Tor Lillqvist + + Fixes contributed by Archaeopteryx Software: This is a first small + part of their changes. Will commit more later. + + * gdk/win32/*.c: Add some more checks for failed GDI calls. If a + call fails, don't use bogus values. + + * gdk/win32/gdkcursor-win32.c (_gdk_win32_data_to_wcursor): Plug + memory leak: g_free() the AND and XOR bitmaps after use. + (_gdk_cursor_destroy): If we are destroying the current Windows + cursor, set the Windows cursor to none first. + + * gdk/win32/gdkgc-win32.c (predraw_set_foreground): Delete the old + brush that was in the DC, like the win32-procution branch does. I + guess this plugs a resource leak? With the HDC cache, the old + brush might be something we created ourselves, and not a stock + brush. And it doesn't do any harm to call DeleteObject on stock + brushes. + + * gdk/win32/gdkwindow-win32.c (gdk_window_impl_win32_finalize): If + the window has a cursor which is the current Windows cursor, + before destroying it set the current Windows cursor to none. + (gdk_window_set_cursor): Also here, if destroying the current + Windows cursor, set the current Windows cursor to none first. + (gdk_window_get_pointer): Revamp logic. + 2002-01-10 jacob berkman * gtk/gtkwidget.c (gtk_widget_add_events): actually iterate diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index bb8b23e187..9d472601d5 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,30 @@ +2002-01-12 Tor Lillqvist + + Fixes contributed by Archaeopteryx Software: This is a first small + part of their changes. Will commit more later. + + * gdk/win32/*.c: Add some more checks for failed GDI calls. If a + call fails, don't use bogus values. + + * gdk/win32/gdkcursor-win32.c (_gdk_win32_data_to_wcursor): Plug + memory leak: g_free() the AND and XOR bitmaps after use. + (_gdk_cursor_destroy): If we are destroying the current Windows + cursor, set the Windows cursor to none first. + + * gdk/win32/gdkgc-win32.c (predraw_set_foreground): Delete the old + brush that was in the DC, like the win32-procution branch does. I + guess this plugs a resource leak? With the HDC cache, the old + brush might be something we created ourselves, and not a stock + brush. And it doesn't do any harm to call DeleteObject on stock + brushes. + + * gdk/win32/gdkwindow-win32.c (gdk_window_impl_win32_finalize): If + the window has a cursor which is the current Windows cursor, + before destroying it set the current Windows cursor to none. + (gdk_window_set_cursor): Also here, if destroying the current + Windows cursor, set the current Windows cursor to none first. + (gdk_window_get_pointer): Revamp logic. + 2002-01-10 jacob berkman * gtk/gtkwidget.c (gtk_widget_add_events): actually iterate diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index bb8b23e187..9d472601d5 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,30 @@ +2002-01-12 Tor Lillqvist + + Fixes contributed by Archaeopteryx Software: This is a first small + part of their changes. Will commit more later. + + * gdk/win32/*.c: Add some more checks for failed GDI calls. If a + call fails, don't use bogus values. + + * gdk/win32/gdkcursor-win32.c (_gdk_win32_data_to_wcursor): Plug + memory leak: g_free() the AND and XOR bitmaps after use. + (_gdk_cursor_destroy): If we are destroying the current Windows + cursor, set the Windows cursor to none first. + + * gdk/win32/gdkgc-win32.c (predraw_set_foreground): Delete the old + brush that was in the DC, like the win32-procution branch does. I + guess this plugs a resource leak? With the HDC cache, the old + brush might be something we created ourselves, and not a stock + brush. And it doesn't do any harm to call DeleteObject on stock + brushes. + + * gdk/win32/gdkwindow-win32.c (gdk_window_impl_win32_finalize): If + the window has a cursor which is the current Windows cursor, + before destroying it set the current Windows cursor to none. + (gdk_window_set_cursor): Also here, if destroying the current + Windows cursor, set the current Windows cursor to none first. + (gdk_window_get_pointer): Revamp logic. + 2002-01-10 jacob berkman * gtk/gtkwidget.c (gtk_widget_add_events): actually iterate diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index bb8b23e187..9d472601d5 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,30 @@ +2002-01-12 Tor Lillqvist + + Fixes contributed by Archaeopteryx Software: This is a first small + part of their changes. Will commit more later. + + * gdk/win32/*.c: Add some more checks for failed GDI calls. If a + call fails, don't use bogus values. + + * gdk/win32/gdkcursor-win32.c (_gdk_win32_data_to_wcursor): Plug + memory leak: g_free() the AND and XOR bitmaps after use. + (_gdk_cursor_destroy): If we are destroying the current Windows + cursor, set the Windows cursor to none first. + + * gdk/win32/gdkgc-win32.c (predraw_set_foreground): Delete the old + brush that was in the DC, like the win32-procution branch does. I + guess this plugs a resource leak? With the HDC cache, the old + brush might be something we created ourselves, and not a stock + brush. And it doesn't do any harm to call DeleteObject on stock + brushes. + + * gdk/win32/gdkwindow-win32.c (gdk_window_impl_win32_finalize): If + the window has a cursor which is the current Windows cursor, + before destroying it set the current Windows cursor to none. + (gdk_window_set_cursor): Also here, if destroying the current + Windows cursor, set the current Windows cursor to none first. + (gdk_window_get_pointer): Revamp logic. + 2002-01-10 jacob berkman * gtk/gtkwidget.c (gtk_widget_add_events): actually iterate diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index bb8b23e187..9d472601d5 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,30 @@ +2002-01-12 Tor Lillqvist + + Fixes contributed by Archaeopteryx Software: This is a first small + part of their changes. Will commit more later. + + * gdk/win32/*.c: Add some more checks for failed GDI calls. If a + call fails, don't use bogus values. + + * gdk/win32/gdkcursor-win32.c (_gdk_win32_data_to_wcursor): Plug + memory leak: g_free() the AND and XOR bitmaps after use. + (_gdk_cursor_destroy): If we are destroying the current Windows + cursor, set the Windows cursor to none first. + + * gdk/win32/gdkgc-win32.c (predraw_set_foreground): Delete the old + brush that was in the DC, like the win32-procution branch does. I + guess this plugs a resource leak? With the HDC cache, the old + brush might be something we created ourselves, and not a stock + brush. And it doesn't do any harm to call DeleteObject on stock + brushes. + + * gdk/win32/gdkwindow-win32.c (gdk_window_impl_win32_finalize): If + the window has a cursor which is the current Windows cursor, + before destroying it set the current Windows cursor to none. + (gdk_window_set_cursor): Also here, if destroying the current + Windows cursor, set the current Windows cursor to none first. + (gdk_window_get_pointer): Revamp logic. + 2002-01-10 jacob berkman * gtk/gtkwidget.c (gtk_widget_add_events): actually iterate diff --git a/gdk/win32/gdkcolor-win32.c b/gdk/win32/gdkcolor-win32.c index 3e4e72bf45..92ae87c398 100644 --- a/gdk/win32/gdkcolor-win32.c +++ b/gdk/win32/gdkcolor-win32.c @@ -473,7 +473,8 @@ create_colormap (HWND w, for (i = logPalettePtr->palNumEntries; i < colormap->sizepalette; i++) colormap->in_use[i] = FALSE; } - ReleaseDC (NULL, hdc); + if (!ReleaseDC (NULL, hdc)) + WIN32_GDI_FAILED ("ReleaseDC"); return colormap; } diff --git a/gdk/win32/gdkcursor-win32.c b/gdk/win32/gdkcursor-win32.c index 2fd723f45d..6fceb2a5d1 100644 --- a/gdk/win32/gdkcursor-win32.c +++ b/gdk/win32/gdkcursor-win32.c @@ -73,6 +73,10 @@ _gdk_win32_data_to_wcursor (GdkCursorType cursor_type) rv = CreateCursor (gdk_app_hmodule, cursors[i].hotx, cursors[i].hoty, w, h, ANDplane, XORplane); + if (rv == NULL) + WIN32_API_FAILED ("CreateCursor"); + g_free (ANDplane); + g_free (XORplane); return rv; } @@ -256,6 +260,9 @@ _gdk_cursor_destroy (GdkCursor *cursor) GDK_NOTE (MISC, g_print ("_gdk_cursor_destroy: %#x\n", (cursor->type == GDK_CURSOR_IS_PIXMAP) ? (guint) private->hcursor : 0)); + if (GetCursor() == private->hcursor) + SetCursor(NULL); + if (!DestroyCursor (private->hcursor)) WIN32_API_FAILED ("DestroyCursor"); diff --git a/gdk/win32/gdkgc-win32.c b/gdk/win32/gdkgc-win32.c index 3862b499f4..670a4bb590 100644 --- a/gdk/win32/gdkgc-win32.c +++ b/gdk/win32/gdkgc-win32.c @@ -948,8 +948,14 @@ predraw_set_foreground (GdkGC *gc, WIN32_GDI_FAILED ("CreateSolidBrush"), *ok = FALSE; break; } - if (*ok && SelectObject (win32_gc->hdc, hbr) == NULL) - WIN32_GDI_FAILED ("SelectObject"), *ok = FALSE; + if (*ok) + { + HBRUSH old_hbr = SelectObject (win32_gc->hdc, hbr); + if (old_hbr == NULL) + WIN32_GDI_FAILED ("SelectObject"), *ok = FALSE; + else if (!DeleteObject (old_hbr)) + WIN32_GDI_FAILED ("DeleteObject"); + } } static void diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index c5562c3df5..4ec814c703 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -140,6 +140,8 @@ gdk_window_impl_win32_finalize (GObject *object) if (window_impl->hcursor != NULL) { + if (GetCursor () == window_impl->hcursor) + SetCursor (NULL); if (!DestroyCursor (window_impl->hcursor)) WIN32_GDI_FAILED("DestroyCursor"); window_impl->hcursor = NULL; @@ -1164,7 +1166,8 @@ _gdk_windowing_window_clear_area (GdkWindow *window, hdc = GetDC (GDK_WINDOW_HWND (window)); IntersectClipRect (hdc, x, y, x + width + 1, y + height + 1); SendMessage (GDK_WINDOW_HWND (window), WM_ERASEBKGND, (WPARAM) hdc, 0); - ReleaseDC (GDK_WINDOW_HWND (window), hdc); + if (!ReleaseDC (GDK_WINDOW_HWND (window), hdc)) + WIN32_GDI_FAILED ("ReleaseDC"); } } @@ -1623,43 +1626,58 @@ gdk_window_set_cursor (GdkWindow *window, impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl); cursor_private = (GdkCursorPrivate*) cursor; - if (!GDK_WINDOW_DESTROYED (window)) + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (!cursor) + hcursor = NULL; + else + hcursor = cursor_private->hcursor; + + GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n", + (guint) GDK_WINDOW_HWND (window), + (guint) hcursor)); + + /* First get the old cursor, if any (we wait to free the old one + * since it may be the current cursor set in the Win32 API right + * now). + */ + hprevcursor = impl->hcursor; + + if (hcursor == NULL) + impl->hcursor = NULL; + else { - if (!cursor) - hcursor = NULL; - else - hcursor = cursor_private->hcursor; + /* We must copy the cursor as it is OK to destroy the GdkCursor + * while still in use for some window. See for instance + * gimp_change_win_cursor() which calls gdk_window_set_cursor + * (win, cursor), and immediately afterwards gdk_cursor_destroy + * (cursor). + */ + if ((impl->hcursor = CopyCursor (hcursor)) == NULL) + WIN32_API_FAILED ("CopyCursor"); + GDK_NOTE (MISC, g_print ("...CopyCursor (%#x) = %#x\n", + (guint) hcursor, (guint) impl->hcursor)); + } - GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n", - (guint) GDK_WINDOW_HWND (window), - (guint) hcursor)); - hprevcursor = impl->hcursor; - if (hcursor == NULL) - impl->hcursor = NULL; - else - { - /* We must copy the cursor as it is OK to destroy the GdkCursor - * while still in use for some window. See for instance - * gimp_change_win_cursor() which calls - * gdk_window_set_cursor (win, cursor), and immediately - * afterwards gdk_cursor_destroy (cursor). - */ - impl->hcursor = CopyCursor (hcursor); - GDK_NOTE (MISC, g_print ("...CopyCursor (%#x) = %#x\n", - (guint) hcursor, (guint) impl->hcursor)); + /* Set new cursor in all cases if we're over our window */ + if (gdk_window_get_pointer(window, NULL, NULL, NULL) == window) + SetCursor (impl->hcursor); - if (hprevcursor != NULL && GetCursor () == hprevcursor) - SetCursor (impl->hcursor); + /* Destroy the previous cursor: Need to make sure it's no longer in + * use before we destroy it, in case we're not over our window but + * the cursor is still set to our old one. + */ + if (hprevcursor != NULL) + { + if (GetCursor() == hprevcursor) + SetCursor (NULL); - if (hprevcursor != NULL) - { - GDK_NOTE (MISC, g_print ("...DestroyCursor (%#x)\n", - (guint) hprevcursor)); - - if (!DestroyCursor (hprevcursor)) - WIN32_API_FAILED ("DestroyCursor"); - } - } + GDK_NOTE (MISC, g_print ("...DestroyCursor (%#x)\n", + (guint) hprevcursor)); + + if (!DestroyCursor (hprevcursor)) + WIN32_API_FAILED ("DestroyCursor"); } } @@ -1827,7 +1845,7 @@ _gdk_windowing_window_get_pointer (GdkWindow *window, GdkModifierType *mask) { GdkWindow *return_val; - POINT pointc, point; + POINT screen_point, point; HWND hwnd, hwndc; g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL); @@ -1836,8 +1854,8 @@ _gdk_windowing_window_get_pointer (GdkWindow *window, window = _gdk_parent_root; return_val = NULL; - GetCursorPos (&pointc); - point = pointc; + GetCursorPos (&screen_point); + point = screen_point; ScreenToClient (GDK_WINDOW_HWND (window), &point); if (x) @@ -1846,17 +1864,28 @@ _gdk_windowing_window_get_pointer (GdkWindow *window, *y = point.y; hwnd = WindowFromPoint (point); - point = pointc; - ScreenToClient (hwnd, &point); - - do { - hwndc = ChildWindowFromPoint (hwnd, point); - ClientToScreen (hwnd, &point); - ScreenToClient (hwndc, &point); - } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */ - - return_val = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd); - + if (hwnd != NULL) + { + gboolean done = FALSE; + + while (!done) + { + point = screen_point; + ScreenToClient (hwnd, &point); + hwndc = ChildWindowFromPoint (hwnd, point); + if (hwndc == NULL) + done = TRUE; + else if (hwndc == hwnd) + done = TRUE; + else + hwnd = hwndc; + } + + return_val = gdk_window_lookup (hwnd); + } + else + return_val = NULL; + if (mask) { BYTE kbd[256]; -- 2.30.2